package files

import (
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"
)

// 按文件名排序，可扩展至文件时间
type byName []os.FileInfo

//func (f byName) Less(i, j int) bool { return f[i].Name() < f[j].Name() } // 文件名升序，默认方式
func (f byName) Less(i, j int) bool { return f[i].Name() > f[j].Name() } // 文件名倒序
func (f byName) Len() int           { return len(f) }
func (f byName) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }

// GetFileListBySuffix returns an ordered list of file paths.
// It recognize if given path is a file, and don't do recursive find.
func GetFileListBySuffix(dirPath, suffix string, needDir bool, isDescend bool, num int) ([]string, error) {
	if !IsExist(dirPath) {
		return nil, fmt.Errorf("given path does not exist: %s", dirPath)
	} else if IsFile(dirPath) {
		return []string{dirPath}, nil
	}

	// Given path is a directory.
	dir, err := os.Open(dirPath)
	if err != nil {
		return nil, err
	}

	fis, err := dir.Readdir(0)
	if err != nil {
		return nil, err
	}

	if isDescend {
		sort.Sort(byName(fis))
	}

	if num == 0 {
		num = len(fis)
	}
	files := make([]string, 0, num)
	for i := 0; i < num; i++ {
		fi := fis[i]
		if strings.HasSuffix(fi.Name(), suffix) {
			if needDir {
				files = append(files, filepath.Join(dirPath, fi.Name()))
			} else {
				files = append(files, fi.Name())
			}
		}
	}

	return files, nil
}

// as GetFileListBySuffix, but for Prefix
func GetFileListByPrefix(dirPath, suffix string, needDir bool, isDescend bool, num int) ([]string, error) {
	if !IsExist(dirPath) {
		return nil, fmt.Errorf("given path does not exist: %s", dirPath)
	} else if IsFile(dirPath) {
		return []string{dirPath}, nil
	}

	// Given path is a directory.
	dir, err := os.Open(dirPath)
	if err != nil {
		return nil, err
	}

	fis, err := dir.Readdir(0)
	if err != nil {
		return nil, err
	}

	if isDescend {
		sort.Sort(byName(fis))
	}

	if num == 0 {
		num = len(fis)
	}
	files := make([]string, 0, num)
	for i := 0; i < num; i++ {
		fi := fis[i]
		if strings.HasPrefix(fi.Name(), suffix) {
			if needDir {
				files = append(files, filepath.Join(dirPath, fi.Name()))
			} else {
				files = append(files, fi.Name())
			}
		}
	}

	return files, nil
}

// 根据关键字查找
func GetFileListByKey(dirPath, key string, needDir bool, isDescend bool, num int) ([]string, error) {
	if !IsExist(dirPath) {
		return nil, fmt.Errorf("given path does not exist: %s", dirPath)
	} else if IsFile(dirPath) {
		return []string{dirPath}, nil
	}

	// Given path is a directory.
	dir, err := os.Open(dirPath)
	if err != nil {
		return nil, err
	}

	fis, err := dir.Readdir(0)
	if err != nil {
		return nil, err
	}

	if isDescend {
		sort.Sort(byName(fis))
	}

	if num == 0 {
		num = len(fis)
	}
	files := make([]string, 0, num)
	for i := 0; i < num; i++ {
		fi := fis[i]
		if strings.Contains(fi.Name(), key) {
			if needDir {
				files = append(files, filepath.Join(dirPath, fi.Name()))
			} else {
				files = append(files, fi.Name())
			}
		}
	}

	return files, nil
}

func IsDir(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return s.IsDir()
}

func IsFile(path string) bool {
	return !IsDir(path)
}

func IsExist(path string) bool {
	_, err := os.Stat(path)
	if err != nil {
		if os.IsExist(err) {
			return true
		}
		return false
	}
	return true
}
